#include "head.h"
#include <func.h>
int exitPipe[2];
void sigFunc(int signum){
    puts("signal is coming!");
    write(exitPipe[1], "1", 1);
}

int main(int argc, char *argv[]){
    // ./server 192.168.31.128 1234 3
    ARGS_CHECK(argc, 4);
    openlog(NULL,LOG_PID,LOG_USER);
    pipe(exitPipe);
    if(fork() != 0){
        close(exitPipe[0]);//close read pipe
        signal(SIGUSR1, sigFunc);
        wait(NULL);
        exit(0);
    }
    close(exitPipe[1]);//close write pipe
    int workerNum = atoi(argv[3]);
    threadPool_t threadPool;
    threadPoolInit(&threadPool, workerNum);
    int sockFd;
    makeWorker(&threadPool);
    tcpInit(argv[1], argv[2], &sockFd);
    int epFd = epoll_create(10);
    epollAdd(sockFd, epFd);
    epollAdd(exitPipe[0], epFd);
    struct epoll_event readyList[2];

    MYSQL *db = mysql_init(NULL);
    initDataBase(db);
    while(1){
        int readyNum = epoll_wait(epFd, readyList, 2, -1);
        puts("epoll ready");
        for(int i=0; i<readyNum; ++i){
            if(readyList[i].data.fd == sockFd){
                int netFd = accept(sockFd, NULL, NULL);
                // printf("netfd = %d\n", netFd);
                char choice;
                recv(netFd, &choice, 1, 0);
                
                int dataLength;
                recv(netFd, &dataLength, sizeof(dataLength), 0);
                // printf("%d\n", dataLength);
                char buf[1024] = {0};
                recv(netFd, buf, dataLength, 0);
                // printf("%s\n", buf);
                char arr[100] = "";
                strcpy(arr, buf);
                char *userName = strtok(arr, " ");
                char *password = strtok(NULL, " ");
                
                
                if(choice == '1'){//登录
                    int isLoginUsrLegal = usrLogin(db, userName, password);
                    send(netFd, &isLoginUsrLegal, 1, MSG_NOSIGNAL);
                    if(isLoginUsrLegal == 1 || isLoginUsrLegal == 2){//密码错误
                        close(netFd);
                        continue;
                    }
                }
                else if(choice == '2'){//注册
                    int isRegisterRight = usrRegister(db, userName, password);
                    if(isRegisterRight == 0){
                        send(netFd, "0", 1, MSG_NOSIGNAL);
                        insertCatalogWhenRegister(db, userName);
                    }
                    else{
                        send(netFd, "1", 1, MSG_NOSIGNAL);
                    }
                }
                

                //记录用户上线
                time_t ttime;
                time(&ttime);
                struct tm *pTm = gmtime(&ttime);
                syslog(LOG_INFO, "%s %04d:%02d:%02d", userName, (1900 + pTm->tm_year), (1 + pTm->tm_mon), (pTm->tm_mday));

                // char curPath[200] = {0};
                // sprintf(curPath, "/%s", userName);
                // puts(curPath);
                // char bashPre[200] = {0};
                // sprintf(bashPre, "%s$", curPath);
                // puts(bashPre);
                // send(netFd, bashPre, strlen(bashPre), 0);

                //char line[200] = {0};
                // char arr1[] = "";
                // strcpy(arr1, line);
                // char *command = strtok(arr1, " ");
                pthread_mutex_lock(&threadPool.mutex);
                enUserQueue(&threadPool.userQueue, netFd, userName);
                puts("new user");
                pthread_cond_signal(&threadPool.cond);
                pthread_mutex_unlock(&threadPool.mutex);
            }
            
            if(readyList[i].data.fd == exitPipe[0]){
                // for(int j=0; j<workerNum; j++){
                //     pthread_cancel(threadPool.tidArr[j]);
                // }
                puts("I am going to die!");
                threadPool.isThreadPoolRunning = 0;
                pthread_cond_broadcast(&threadPool.cond);
                for(int j=0; j<workerNum; ++j){
                    pthread_join(threadPool.tidArr[j], NULL);
                }
                puts("exit");
                exit(0);
            }
        }
    }
    closelog();
}